// ========== Copyright Header Begin ==========================================
// 
// OpenSPARC T1 Processor File: InstructionWord.cc
// Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// 
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// 
// The above named program is distributed in the hope that it will be 
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// 
// ========== Copyright Header End ============================================
/************************************************************************
**  
**  Copyright (C) 2002, Sun Microsystems, Inc.
**
**  Sun considers its source code as an unpublished, proprietary
**  trade secret and it is available only under strict license provisions.
**  This copyright notice is placed here only to protect Sun in the event 
**  the source is deemed a published work. Disassembly, decompilation,
**  or other means of reducing the object code to human readable form
**  is prohibited by the license agreement under which this code is
**  provided to the user or company in possession of this copy."
**
*************************************************************************/
#include "InstructionWord.h"
#include "Util/NumericUtils.h"
#include "StdMacros.h"
#include "spix_sparc.h"
#include <cstring>
#include <sstream>

#define SET_ONES( bits ) ((1ULL << (bits))-1)
#define GET_BITS( lw, hi, lo ) ((lw >> lo) & SET_ONES(hi - lo + 1))
#define SET_BITS( lw, hi, lo, v ) (lw=((lw & ~(SET_ONES(hi - lo + 1) << lo))|(((v&SET_ONES(hi - lo + 1)) << lo))))
/* #define SET_BITS( lw, hi, lo, v ) (lw=((lw)|(v << lo))) */



using namespace std;
using namespace Riesling;

const size_t InstructionWord::SPIX_BUFFER_SIZE = 256;

bool InstructionWord::operator==( const InstructionWord & rhs ) const
{ 
    return (strand_ == rhs.strand_ && iw_ == rhs.iw_ && 
	    vpc_ == rhs.vpc_ && annulled_ == rhs.annulled_ &&
	    rs1_ofs == rhs.rs1_ofs && rs2_ofs == rhs.rs2_ofs && 
	    rhs.rs3_ofs == rs3_ofs && rd_ofs == rhs.rd_ofs &&
	    OpcodeValid_ == rhs.OpcodeValid_ && Opcode_ == rhs.Opcode_ && 
	    instAlignSize_ == rhs.instAlignSize_ && sir_ == rhs.sir_ &&
	nonzbitsFpu == rhs.nonzbitsFpu && instrTypeFpu == rhs.instrTypeFpu);
}

/////////////////////////////////////////////////////////

string InstructionWord::toString() const
{
     uint32_t l_op = op();
     uint32_t l_op3 = op3();
     uint32_t l_rd = rd() & 0x1f;

     if ( (l_op == 0x2) && ((l_op3 == 0x30) && (l_rd == 0x4)) ) 
     {
	 // wrasr ..., %asr4 / write tick register
	 static const  string regn = "goli";
	 ostringstream os;
	 uint32_t l_rs1 = rs1();
	 
	 os << "wrasr   ";
	 os << "%" << regn[l_rs1/8] << l_rs1%8;
	 os << ", ";
	 
	 if( i() )
	 {
	     uint32_t l_imm13 = simm13();
	     os << "0x" << hex << l_imm13;
	 }
	 else
	 {
	     uint32_t l_rs2 = rs2();
	     os << "%" << regn[l_rs2/8] << l_rs2%8;
	 }
	 
	 os << ", ";
	 os << "%asr" << dec << l_rd;

	 return os.str();
     }
     else 
     {
	 char buffer[SPIX_BUFFER_SIZE];
	 if( ! spix_sparc_dis( &buffer[0], SPIX_BUFFER_SIZE, spix_sparc_iop( SPIX_SPARC_V9, &iw_), &iw_, vpc_ ) ){
	     RIESLING_THROW_DOMAIN_ERROR( "Error deccoding instruction." );
	 }

	 if( annulled_ ){
	     strncat( buffer, " [annulled]", SPIX_BUFFER_SIZE );
	 }

         if (rd_ofs || rs1_ofs || rs2_ofs || rs3_ofs)
         {
           char tmp[] = " <w,w,w,w>";
           if (rs1_ofs) tmp[2] = 't';
           if (rs2_ofs) tmp[4] = 't';
           if (rs3_ofs) tmp[6] = 't';
           if (rd_ofs)  tmp[8] = 't';
           strncat(buffer,tmp,SPIX_BUFFER_SIZE);
         }
     
	 return buffer;
     }
}

/////////////////////////////////////////////////////////

uint32_t InstructionWord::cc1() const 
{
    if ( op() == 0 ) {
        return GET_BITS( iw_, 21, 21 );
    } else if ( op() == 2 ) {
	if ((op3() == 0x35) || (op3() == 0x36)) {
	    return GET_BITS( iw_, 26, 26 );
	} else {
	    return GET_BITS( iw_, 12, 12 );
	}
    } else {
        RIESLING_THROW_DOMAIN_ERROR( "No cc1 for this opcode." );
    }
}
    
/////////////////////////////////////////////////////////

uint32_t  InstructionWord::cc0() const 
{
    if ( op() == 0 ) {
        return GET_BITS( iw_, 20, 20 );
    } else if ( op() == 2 ) {
	if ((op3() == 0x35) || (op3() == 0x36)) {
	    return GET_BITS( iw_, 25, 25 );
	} else {
	    return GET_BITS( iw_, 11, 11 );
	}
    } else {
        RIESLING_THROW_DOMAIN_ERROR( "No cc0 for this opcode." );
    }
}

/////////////////////////////////////////////////////////

uint32_t InstructionWord::get( uint8_t hi, uint8_t lo ) const 
{
    return GET_BITS( iw_, hi, lo );
}

/////////////////////////////////////////////////////////

void 
InstructionWord::op( uint32_t value )
{
    SET_BITS( iw_, 31, 30, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::op2( uint32_t value )
{
    SET_BITS( iw_, 24, 22, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::op3( uint32_t value )
{
    SET_BITS( iw_, 24, 19, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::opf( uint32_t value )
{
    SET_BITS( iw_, 13, 5, value );
}


/////////////////////////////////////////////////////////

void InstructionWord::rd( uint32_t value )
{
  if (value >= 32)
  {
    value -= 32;
    rd_ofs = 32;
  }
  SET_BITS( iw_, 29, 25, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::rs1( uint32_t value )
{
  if (value >= 32)
  {
    value -= 32;
    rs1_ofs = 32;
  }
  SET_BITS( iw_, 18, 14, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::rs2( uint32_t value )
{
  if (value >= 32)
  {
    value -= 32;
    rs2_ofs = 32;
  }
  SET_BITS( iw_, 4, 0, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::rs3( uint32_t value )
{
  if (value >= 32)
  {
    value -= 32;
    rs3_ofs = 32;
  }
  SET_BITS( iw_, 13, 9, value );
}

/////////////////////////////////////////////////////////

void 
InstructionWord::i( uint32_t value )
{
    SET_BITS( iw_, 13, 13, value );
}

/////////////////////////////////////////////////////////

void 
InstructionWord::immAsi( uint32_t value )
{
    SET_BITS( iw_, 12, 5, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::disp30( uint32_t value )
{
    SET_BITS( iw_, 29, 0, value );
}
    
/////////////////////////////////////////////////////////

void InstructionWord::imm22( uint32_t value )
{
    SET_BITS( iw_, 21, 0, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::a( uint32_t value )
{
    SET_BITS( iw_, 29, 29, value );
}    


/////////////////////////////////////////////////////////

void InstructionWord::p( uint32_t value )
{
    SET_BITS( iw_, 19, 19, value );
}    


/////////////////////////////////////////////////////////

void InstructionWord::disp19( uint32_t value )
{
    SET_BITS( iw_, 18, 0, value );
}    

/////////////////////////////////////////////////////////

void InstructionWord::disp22( uint32_t value )
{
    SET_BITS( iw_, 21, 0, value );
}    

/////////////////////////////////////////////////////////

void InstructionWord::disp16( uint32_t value )
{
    SET_BITS( iw_, 13, 0, value );
    SET_BITS( iw_, 21, 20, value >> 20 );
}

/////////////////////////////////////////////////////////

void InstructionWord::fmt2CC( uint32_t value )
{
    SET_BITS( iw_, 21, 20, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::cond( uint32_t value )
{
    if ( (op() == 0x0) || ((op() == 0x2) && (op3() == 0x3A)) ) {
       SET_BITS( iw_, 28, 25, value );
    } else {
       SET_BITS( iw_, 17, 14, value );
    }
}

/////////////////////////////////////////////////////////

void InstructionWord::rcond( uint32_t value )
{
    if (op() == 0x0)
	SET_BITS( iw_, 27, 25, value );
    else
	SET_BITS( iw_, 12, 10, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::simm13( int64_t value )
{
    SET_BITS( iw_, 12, 0, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::simm11( int64_t value)
{
    SET_BITS( iw_, 10, 0, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::simm10( int64_t value )
{
    SET_BITS( iw_, 9, 0, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::movCC( uint8_t value)
{
    RIESLING_THROW_DOMAIN_ERROR( "Unimplemented function." );
    // FIXME
    //return (SET_BITS(iw_,18,18) << 2 ) | GET_BITS(iw_,12,11);
}


/////////////////////////////////////////////////////////

void InstructionWord::x( uint32_t value )
{
    SET_BITS( iw_, 12, 12, value );
}


/////////////////////////////////////////////////////////

void InstructionWord::cc1( uint32_t value)
{
    if ( op() == 0 ) {
        SET_BITS( iw_, 21, 21, value );
    } else if ( op() == 2 ) {
	if ((op3() == 0x35) || (op3() == 0x36)) {
	    SET_BITS( iw_, 26, 26, value );
	} else {
	    SET_BITS( iw_, 12, 12, value );
	}
    } else {
        RIESLING_THROW_DOMAIN_ERROR( "No cc1 for this opcode." );
    }
}
    
/////////////////////////////////////////////////////////

void InstructionWord::opf_cc( uint32_t value )
{
    SET_BITS( iw_, 13, 11, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::cc0( uint32_t value )
{
    if ( op() == 0 ) {
        SET_BITS( iw_, 20, 20, value );
    } else if ( op() == 2 ) {
	if ((op3() == 0x35) || (op3() == 0x36)) {
	    SET_BITS( iw_, 25, 25, value );
	} else {
	    SET_BITS( iw_, 11, 11, value );
	}
    } else {
        RIESLING_THROW_DOMAIN_ERROR( "No cc0 for this opcode." );
    }
}

/////////////////////////////////////////////////////////

void InstructionWord::cc2( uint32_t value )  
{
    SET_BITS( iw_, 18, 18, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::swTrapNr( uint8_t value )
{
    SET_BITS( iw_, 6, 0, value );
}
    
/////////////////////////////////////////////////////////

void InstructionWord::trapCC( uint8_t value )
{
    SET_BITS( iw_, 12, 11, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::shcnt32( uint32_t value )
{
    SET_BITS( iw_, 4, 0, value );
}

/////////////////////////////////////////////////////////

void InstructionWord::shcnt64( uint32_t value)
{
    SET_BITS( iw_, 5, 0, value );
}

/////////////////////////////////////////////////////////

uint_t InstructionWord::decodeSingleReg( uint_t encReg )
{
    return encReg;    
}

/////////////////////////////////////////////////////////

uint_t InstructionWord::decodeDoubleReg( uint_t encReg )
{
    return (((encReg) & ~0x1) | (((encReg) & 0x1) << 5));
}

/////////////////////////////////////////////////////////

uint_t InstructionWord::decodeQuadReg( uint_t encReg )
{
    return (((encReg) & ~0x3) | (((encReg) & 0x1) << 5));
}

/////////////////////////////////////////////////////////

void InstructionWord::setOpcodeValid( bool OpcodeValid )
{
    OpcodeValid_ = OpcodeValid;
}

/////////////////////////////////////////////////////////

void InstructionWord::setOpcode( OpcodeT Opcode )
{
    Opcode_ = Opcode;
}

/////////////////////////////////////////////////////////

// This function checks only for reserved fields that are nonzero.  It 
// is not an exhaustive check for illegal instructions.  Instruction fields
// defined in the V9 manual with the with a "--" should be zeroed.  However,
// some past implementation have not trapped on a nonzero bit pattern in these
// fields.   

bool InstructionWord::fguNonZeroReservedBits() const
{
    bool result = false;

    if( op() == 2 ){
	switch( op3() ){
	    ///////////////////////////////////////////////////////////
	    case 0x34: // FP operations
	    {
		uint_t bits_8_4 = opf() >> 4;
		uint_t bits_3_0 = opf() & 0x0f;
		bool compareBits = false;
		switch( bits_8_4 ){
		    case 0x8:
			switch( bits_3_0 ){
			    case 0x1: // A.14 from V9 Instr Defns
			    case 0x2:
			    case 0x3:

			    case 0x4: // A.16 from V9 Instr Defns
			    case 0x8:
			    case 0xc:
				compareBits = true;
				break;
			}
			break;
		    case 0xd:
			if( bits_3_0 > 0 && bits_3_0 < 4 ){
			    compareBits = true;
			}
			break;
		    case 0xc:
			switch( bits_3_0 ){
			    case 0x9: // A.15 from V9 Instr Defns
			    case 0xd:
			    case 0x6:
			    case 0xe:
			    case 0x7:
			    case 0xb:

			    case 0x4: // A.16 from V9 Instr Defns
			    case 0x8:
			    case 0xc:
				compareBits = true;
				break;
			}
			break;
		    case 0x0:
			switch( bits_3_0 ){
			    case 0x1:
			    case 0x2:
			    case 0x3:
			    case 0x5:
			    case 0x6:
			    case 0x7:
			    case 0x9:
			    case 0xa:
			    case 0xb:
				compareBits = true;
				break;
			}
			break;
		    case 0x2:
			if( bits_3_0 == 0x9 || bits_3_0 == 0xa || bits_3_0 == 0xb ){
			    compareBits = true;
			}
			break;
		} // switch( bits_8_4 )

		if( compareBits && NumericUtils::getBits( iw_, 18, 14 ) != 0 ){
		    result = true;
		}
		break;
	    }

	    case 0x36: // extended or VIS operations
	    {
		uint_t opf_bits = opf();
		switch( opf_bits ){
		    case 0x060:   // FZERO
		    case 0x061:   // FZEROS
		    case 0x07E:   // FONE
		    case 0x07F:   // 13.5.6 Logical Operate Instructions in USII User's Manual 1997
		    {
			if( ( NumericUtils::getBits( iw_, 18, 14 ) != 0 ) ||
			    ( NumericUtils::getBits( iw_, 4, 0 ) != 0 ) ){
			    result = true;
			}
		    }
		    break;

		    case 0x074:   // FSRC1
		    case 0x075:   // FSRC1S
		    case 0x06A:   // FNOT1
		    case 0x06B:   // 13.5.6 Logical Operate Instructions in USII User's Manual 1997
		    {
			if( NumericUtils::getBits( iw_, 4, 0 ) != 0 ){
			    result = true;
			}
		    }
		    break;

		    case 0x078:   // FSRC2
		    case 0x079:   // FSRC2S
		    case 0x066:   // FNOT2
		    case 0x067:   // 13.5.6 Logical Operate Instructions in USII User's Manual 1997
		    case 0x03B:   // FPACK16
		    case 0x03D:   // FPACKFIX
		    case 0x04D:   // 13.5.3 Logical Operate Instructions in USII User's Manual 1997
		    {
			if( NumericUtils::getBits( iw_, 18, 14 ) != 0 ){
			    result = true;
			}
		    }
		    break;

		    case 0x017:   // LZD     Vis3.0
		    case 0x1C4:   // SFiTOs  Vis3.0
		    case 0x1D1:   // SFsTOi  Vis3.0
		    {
			if( NumericUtils::getBits( iw_, 18, 14 ) != 0 ){
			    result = true;
			}
		    }
		    break;

		    case 0x081:   // SIAM Vis2.0
		    {
			if( NumericUtils::getBits( iw_, 29, 25 ) != 0 ){
			    result = true;
			} else if( NumericUtils::getBits( iw_, 18, 14 ) != 0 ){
			    result = true;
			} else if( NumericUtils::getBits( iw_, 4, 3 ) != 0 ){
			    result = true;
			}
		    }
		    break;

		    case 0x109:   // SFABSs Vis3.0
		    case 0x105:   // SFNEGs Vis3.0
		    {
			if( NumericUtils::getBits( iw_, 18, 14 ) != 0 ){
			    result = true;
			}
		    }
		    break;

		    case 0x151:   // FLCMPS Vis3.0
		    case 0x152:   // FLCMPD Vis3.0
		    {
			if( NumericUtils::getBits( iw_, 29, 27 ) != 0 ){
			    result = true;
			}
		    }
		    break;

		    case 0x171:   // SFCMPEQs Vis3.0
		    case 0x173:   // SFCMPNEs Vis3.0
		    case 0x175:   // SFCMPGTs Vis3.0
		    case 0x177:   // SFCMPLEs Vis3.0
		    {
			if( NumericUtils::getBits( iw_, 29, 25 ) != 0 ){
			    result = true;
			}
		    }
		    break;
		}
	    }
	    break;

	} // switch
    } 

    return result;
}

bool InstructionWord::isStoreAsi() const
{
    if( OpcodeValid_ == false ){
	RIESLING_THROW_DOMAIN_ERROR( "isStoreAsi called with OpcodeValid_ == false." );
    }

    switch( Opcode_ ){
	case STBA:
	case STHA:
	case STWA:
	case STXA:
	case STDA:
	case STFA:
	case STDFA:
	case STQFA:
	    return true;
	    break;
	default:
	    return false;
	    break;
    }
}

bool InstructionWord::isLoadAsi() const
{
    if( OpcodeValid_ == false ){
	RIESLING_THROW_DOMAIN_ERROR( "isLoadAsi called with OpcodeValid_ == false." );
    }

    switch( Opcode_ ){
	case LDSBA:
	case LDSHA:
	case LDSWA:
	case LDUBA:
	case LDUHA:
	case LDUWA:
	case LDXA:
	case LDDA:
	case LDFA:
	case LDDFA:
	case LDQFA:
	    return true;
	    break;
	default:
	    return false;
	    break;
    }
}

bool InstructionWord::nonzbitstest1()
{
  return (i() == 0 && NumericUtils::getBits(iw_, 12, 5) != 0);
}

bool InstructionWord::nonzbitstestsll()
{
  if (i() == 0 || (i() == 1 && x() == 0))
    return (NumericUtils::getBits(iw_, 11, 5) != 0);
  else
    return (NumericUtils::getBits(iw_, 11, 6) != 0);
}

bool InstructionWord::nonzbitstestrdasr()
{
  if (i() == 0)			// RDASR and STBAR
    return (NumericUtils::getBits(iw_, 12, 0) != 0);
  else if (i() == 1 && rs1() == 15 && rd() == 0) // MEMBAR
    return (NumericUtils::getBits(iw_, 12, 7) != 0);
  return false;
}

bool InstructionWord::nonzbitstestrdpr()
{
  return (NumericUtils::getBits(iw_, 13, 0) != 0);
}

bool InstructionWord::nonzbitstestflushw()
{
  return (NumericUtils::getBits(iw_, 29, 25) != 0 ||
	  NumericUtils::getBits(iw_, 18, 14) != 0 ||
	  NumericUtils::getBits(iw_, 12, 0) != 0);
}

bool InstructionWord::nonzbitstestmovcc()
{
  return (i() == 0 && NumericUtils::getBits(iw_, 10, 5) != 0);
}

bool InstructionWord::nonzbitstestpopc()
{
  return ((i() == 0 && NumericUtils::getBits(iw_, 12, 5) != 0) ||
	  (NumericUtils::getBits(iw_, 18, 14) != 0));
}

bool InstructionWord::nonzbitstestmovr()
{
  return (i() == 0 && NumericUtils::getBits(iw_, 9, 5) != 0);
}

bool InstructionWord::nonzbitstestsaved()
{
  return (NumericUtils::getBits(iw_, 18, 0) != 0);
}

bool InstructionWord::nonzbitstestreturn()
{
  return ((i() == 0 && NumericUtils::getBits(iw_, 12, 5) != 0) ||
	  NumericUtils::getBits(iw_, 29, 25) != 0);
}

bool InstructionWord::nonzbitstesttcc()
{
  if (NumericUtils::getBits(iw_, 29, 29) != 0)
    return true;
  if (i() == 0)
    return (NumericUtils::getBits(iw_, 10, 5) != 0);
//#ifndef RS_MPSAS_COMPATIBLE
  else
      return (NumericUtils::getBits(iw_, 10, 8) != 0);
//#endif
  return false;
}

bool InstructionWord::nonzbitstestflush()
{
  return (NumericUtils::getBits(iw_, 29, 25) != 0 ||
	  (i() == 0 && NumericUtils::getBits(iw_, 12, 5) != 0));
}

bool InstructionWord::nonzbitstestretry()
{
  return (NumericUtils::getBits(iw_, 18, 0) != 0);
}

bool InstructionWord::nonzbitstestcasa()
{
  return (i() == 1 && NumericUtils::getBits(iw_, 12, 5) != 0);
}

// TODO instAlignSize_ of LDDF, LDQF, STDFA etc needs to be reviewed

void InstructionWord::decodeOpcode()
{
    //Opcode_ = UNDEFINED_INSTR;
    //OpcodeValid_ = true;
    //instAlignSize_ = 0;
    //nonzbits_ = false;
    //illegalInstr_ = false;

    uint tmp;

    switch (op()) {
    case 0:
	switch (op2()) {
	case 0: // ILLTRAP
	    illegalInstr_ = true;
	    break;
	case 1: // BPcc
	    // illegal_instruction (cc0 = 1)
	    tmp = cond();
	    //if ((tmp != 0x8) && (tmp != 0x0)) {
	    if (cc0() == 1) {
		illegalInstr_ = true;
	    }
	    //}
	    break;
	case 2: // Bicc
	    break;
	case 3: // BPr
	    // illegal_instruction (bit 28 = 1, or rcond = 000b or 100b)
	    tmp = rcond();
	    if (((iw_ >> 28) & 0x1) || (tmp == 0x0) || (tmp == 0x4)) {
		illegalInstr_ = true;
	    }
	    break;
	case 4: // SETHI, NOP
	    break;
	case 5: // FBPfcc
	case 6: // FBfcc
	    decodeFpuOpcode();
	    break;
	default:
	    illegalInstr_ = true;
	    break;
	}
	break;

    case 1: // CALL
	break;

    case 2:
	switch (op3()) {
	case 0:			// ADD
	case 1:			// AND
	case 2:			// OR
	case 3:			// XOR
	case 4:			// SUB
	case 5:			// ANDN
	case 6:			// ORN
	case 7:			// XNOR
	case 8:			// ADDC
	case 9:			// MULX
	case 0xa:			// UMUL
	case 0xb:			// SMUL
	case 0xc:			// SUBC
	case 0xd:			// UDIVX
	case 0xe:			// UDIV
	case 0xf:			// SDIV
	    nonzbits_ = nonzbitstest1();
	    break;

	case 0x10:			// ADDCC
	case 0x11:			// ANDCC
	case 0x12:			// ORCC
	case 0x13:			// XORCC
	case 0x14:			// SUBCC
	case 0x15:			// ANDNCC
	case 0x16:			// ORNCC
	case 0x17:			// XNORCC
	case 0x18:			// ADDCCC
	case 0x1a:			// UMULCC
	case 0x1b:			// SMULCC
	case 0x1c:			// SUBCCC
	case 0x1e:			// UDIVCC
	case 0x1f:			// SDIVCC
	    nonzbits_ = nonzbitstest1();
	    break;
	case 0x19:
	case 0x1d:
	    illegalInstr_ = true;
	    break;

	case 0x20:			// TADDCC
	case 0x21:			// TSUBCC
	case 0x22:			// TADDCCTV
	case 0x23:			// TSUBCCTV
	case 0x24:			// MULSCC ---> illegalInstr???
	    nonzbits_ = nonzbitstest1();
	    break;
	case 0x25:			// SLL
	case 0x26:			// SRL
	case 0x27:			// SRA
	    nonzbits_ = nonzbitstestsll();
	    break;
	case 0x28: // RDASR
	    //TODO  privileged_opcode can only be checked at runtime, this
	    //      applies to all instrs with possible privileged_opcode trap.
	    // privileged_opcode (RDSOFTINT, RDTICK_CMPR, and RDSTICK,
	    //                    RDSTICK_CMPR, and RDPCR)
	    // illegal_instruction (RDASR with rs1 = 1 or 7-14;
	    //                      RDASR with rs1 = 15 and rd != 0;
	    //                      RDASR with rs1 != 15 and i = 1;
	    //                      RDASR with rs1 = 16-18, 20-21, or 26-31)
	    Opcode_ = RDASR; 
	    nonzbits_ = nonzbitstestrdasr(); 
	    tmp = rs1();
	    if ((tmp == 1) || (tmp >= 7 && tmp <= 14) ||
		(tmp == 15 && rd() != 0) || (tmp != 15 && i() == 1) ||
		(tmp == 18) || (tmp == 20) || (tmp == 21) || 
		(tmp >= 26 && tmp <= 31)) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x2a: // RDPR
	    //TODO  runtime check: ((rs1 <= 3) and (TL = 0))
	    // privileged_opcode ((PSTATE.priv = 0) and (HSTATE.hpriv = 0))
	    // illegal_instruction ((rs1 = 15-31) or ((rs1 <= 3) and (TL = 0)))
	    Opcode_ = RDPR; 
	    nonzbits_ = nonzbitstestrdpr(); 
	    tmp = rs1();
	    if ((tmp == 15) || (tmp >= 17 && tmp <= 31)) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x2b: // FLUSHW
	    nonzbits_ = nonzbitstestflushw(); 
	    if (i() == 1) { //???
		illegalInstr_ = true;
	    }
	    break;
	case 0x2c: // MOVCC
	    // illegal_instruction (cc2 :: cc1 :: cc0 = 101b or 111b)
	    nonzbits_ = nonzbitstestmovcc(); 
	    if ((cc2() == 1) && (cc0() == 1)) { //???
		illegalInstr_ = true;
	    }
	    break;
	case 0x2d:			// SDIVX
	    nonzbits_ = nonzbitstest1(); break;
	case 0x2e: // POPC
	    nonzbits_ = nonzbitstestpopc(); 
	    if (rs1() > 0) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x2f: // MOVR
	    // illegal_instruction (rcond = 000b or 100b)
	    nonzbits_ = nonzbitstestmovr(); 
	    tmp = rcond();
	    if ((tmp == 0x0) || (tmp == 0x4)) {
		illegalInstr_ = true;
	    }
	    break;

	case 0x30:
	    //TODO  runtime check: WRSTICK (outside of hyperprivileged mode)
	    // privileged_opcode (WRSOFTINT_SET, WRSOFTINT_CLR, WRSOFTINT,
	    //                    WRTICK_CMPR, and WRSTICK_CMPR,)
	    // illegal_instruction (WRSTICK (outside of hyperprivileged mode),
	    //                     (WRASR with rd = 1, 4, 5, 7-14, 16-18, 26-31;
	    //                      WRASR with rd = 15 and (rs1 != 0 or i != 1))
	    Opcode_ = WRASR; 
	    nonzbits_ = nonzbitstest1(); 
	    tmp = rd();
	    if ((tmp == 1) || (tmp == 4) || (tmp == 5) ||
		(tmp >= 7 && tmp <= 14) || 
		(tmp == 15 && (rs1() != 0 || i() != 1)) ||
		(tmp == 18) || (tmp >= 26 && tmp <= 31)) {
		illegalInstr_ = true;
	    }
	    else if (rd() == 15 && (rs1() != 0 || i() == 0)) {
		illegalInstr_ = true;
	    }
	    else if (rd() == 15 && rs1() == 0 && i() == 1) {
		sir_ = true;
	    }
	    break;
	case 0x31: // RESTORED & SAVED 
	    // privileged_opcode (PSTATE.priv = 0)
	    Opcode_ = SAVED; 
	    nonzbits_ = nonzbitstestsaved(); 
	    if (fcn() > 5) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x32: // WRPR
	    //TODO  runtime check: ((rd <= 3) and (TL = 0))
	    //                     (rd = 4 (TICK) outside of hyperprivileged mode)
	    // privileged_opcode ((PSTATE.priv = 0) and (HSTATE.hpriv = 0))
	    // illegal_instruction ((rd = 15-31) or ((rd <= 3) and (TL = 0)),
	    //                      (rd = 4 (TICK) outside of hyperprivileged mode)
	    Opcode_ = WRPR; 
	    nonzbits_ = nonzbitstest1(); 
	    tmp = rd();
	    if ((tmp == 15) || (tmp >= 17 && tmp <= 31)) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x34: // FPop1
	case 0x35: // FPop2
	    decodeFpuOpcode();
	    break;
	case 0x36: // SHUTDOWN / extended or VIS operations
	    // privileged_opcode
	    if (opf() == 0x080) {
		// 13.2 SHUTDOWN instruction in USII User's Manual 1997
		nonzbits_ = (NumericUtils::getBits(iw_, 29, 25) != 0)
		    || (NumericUtils::getBits(iw_, 18, 14) != 0)
		    || (NumericUtils::getBits(iw_, 4, 0) != 0);
	    }
	    else {
		decodeFpuOpcode();
	    }
	    break;
	case 0x37: // FMAf 
	    decodeFpuOpcode();
	    break;
	case 0x38:
	    Opcode_ = JMPL; instAlignSize_= 4; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x39:
	    Opcode_= RETURN; instAlignSize_= 4; nonzbits_= nonzbitstestreturn();
	    break;
	case 0x3a: // Tcc
	    //TODO  runtime check: ((PSTATE.priv = 0) and (SWTN > 127))
	    // illegal_instruction 
	    //   ((cc0 = 1) or
	    //   ((PSTATE.priv = 0) and (SWTN > 127)) or
	    //   (instruction<29> != 0) or
	    //   ((i = 0) and (instruction<10:5> != 0)) or
	    //   ((i = 1) and (instruction<10:8> != 0)))
	    Opcode_ = TCC; 
	    nonzbits_ = nonzbitstesttcc(); 
	    if (cc0() == 1) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x3b:
	    Opcode_= FLUSH; instAlignSize_= 1; nonzbits_= nonzbitstestflush();
	    break;
	case 0x3c:			// SAVE
	case 0x3d:			// RESTORE
	    nonzbits_ = nonzbitstest1();
	    break;
	case 0x3e: // DONE & RETRY
	    //TODO  runtime check: (TL = 0)
	    // privileged_opcode (PSTATE.priv = 0)
	    // illegal_instruction (TL = 0)
	    Opcode_ = RETRY; 
	    nonzbits_ = nonzbitstestretry(); 
	    if (fcn() > 1) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x3f: // FMAu
	    decodeFpuOpcode();
	    break;
	default:
	    illegalInstr_ = true;
	    break;
	}
	break;

    case 3:
	switch (op3()) {
	case 0:
	    Opcode_ = LDUW; instAlignSize_ = 4; nonzbits_ = nonzbitstest1(); 
	    break;
	case 1:
	    Opcode_ = LDUB; instAlignSize_ = 1; nonzbits_ = nonzbitstest1();
	    break;
	case 2:
	    Opcode_ = LDUH; instAlignSize_ = 2; nonzbits_ = nonzbitstest1(); 
	    break;
	case 3: // LDD
	    // illegal_instruction(LDD with odd rd)
	    Opcode_ = LDD; 
	    instAlignSize_ = 8; 
	    nonzbits_ = nonzbitstest1(); 
	    if (rd() & 0x1) {
		illegalInstr_ = true;
	    }
	    break;
	case 4:
	    Opcode_ = STW; instAlignSize_ = 4; nonzbits_ = nonzbitstest1();
	    break;
	case 5:
	    Opcode_ = STB; instAlignSize_ = 1; nonzbits_ = nonzbitstest1(); 
	    break;
	case 6:
	    Opcode_ = STH; instAlignSize_ = 2; nonzbits_ = nonzbitstest1(); 
	    break;
	case 7: // STD
	    // illegal_instruction(STD with odd rd)
	    Opcode_ = STD; 
	    instAlignSize_ = 8; 
	    nonzbits_ = nonzbitstest1(); 
	    if (rd() & 0x1) {
		illegalInstr_ = true;
	    }
	    break;
	case 8:
	    Opcode_ = LDSW; instAlignSize_ = 4; nonzbits_ = nonzbitstest1();
	    break;
	case 9:
	    Opcode_ = LDSB; instAlignSize_ = 1; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0xa:
	    Opcode_ = LDSH; instAlignSize_ = 2; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0xb:
	    Opcode_ = LDX; instAlignSize_ = 8; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0xc: illegalInstr_ = true; break;
	case 0xd:
	    Opcode_ = LDSTUB; instAlignSize_ = 1; nonzbits_ = nonzbitstest1();
	    break;
	case 0xe:
	    Opcode_ = STX; instAlignSize_ = 8; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0xf:
	    Opcode_ = SWAP; instAlignSize_ = 4; nonzbits_ = nonzbitstest1();
	    break;

	case 0x10: Opcode_ = LDUWA; instAlignSize_ = 4; break;
	case 0x11: Opcode_ = LDUBA; instAlignSize_ = 1; break;
	case 0x12: Opcode_ = LDUHA; instAlignSize_ = 2; break;
	case 0x13: // LDDA
	    //illegal_instruction(LDDA with odd rd)
	    Opcode_ = LDDA; 
	    instAlignSize_ = 8; 
	    if (rd() & 0x1) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x14: Opcode_ = STWA; instAlignSize_ = 4; break;
	case 0x15: Opcode_ = STBA; instAlignSize_ = 1; break;
	case 0x16: Opcode_ = STHA; instAlignSize_ = 2; break;
	case 0x17: // STDA
	    //illegal_instruction(STDA with odd rd)
	    Opcode_ = STDA; 
	    instAlignSize_ = 8; 
	    if (rd() & 0x1) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x18: Opcode_ = LDSWA; instAlignSize_ = 4; break;
	case 0x19: Opcode_ = LDSBA; instAlignSize_ = 1; break;
	case 0x1a: Opcode_ = LDSHA; instAlignSize_ = 2; break;
	case 0x1b: Opcode_ = LDXA; instAlignSize_ = 8; break;
	case 0x1c: illegalInstr_ = true; break;
	case 0x1d: Opcode_ = LDSTUBA; instAlignSize_ = 1; break;
	case 0x1e: Opcode_ = STXA; instAlignSize_ = 8; break;
	case 0x1f: Opcode_ = SWAPA; instAlignSize_ = 4; break;

	case 0x20:
	    Opcode_ = LDF; instAlignSize_ = 4; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x21:
	    // illegal_instruction (op3=21x and rd = 2-31)
	    if (rd() == 0) {
		Opcode_ = LDFSR;
		instAlignSize_ = 4;
	    }
	    else if (rd() == 1) {
		Opcode_ = LDXFSR;
		instAlignSize_ = 8;
	    }
	    else {
		illegalInstr_ = true;
	    }
	    nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x22:
	    // LDQF{A}/STQF{A} are not directly executed in hardware; they 
	    // cause an illegal_instruction trap.
	    Opcode_ = LDQF; instAlignSize_ = 4; nonzbits_ = nonzbitstest1(); 
	    illegalInstr_ = true;
	    break;
	case 0x23:
	    Opcode_ = LDDF; instAlignSize_ = 8; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x24:
	    Opcode_ = STF; instAlignSize_ = 4; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x25:
	    // illegal_instructionop3 = 25x and rd = 2-31
	    if (rd() == 0) {
		Opcode_ = STFSR;
		instAlignSize_ = 4;
	    }
	    else if (rd() == 1) {
		Opcode_ = STXFSR;
		instAlignSize_ = 8;
	    }
	    else {
		illegalInstr_ = true;
	    }
	    nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x26:
	    Opcode_ = STQF; instAlignSize_ = 4; nonzbits_ = nonzbitstest1(); 
	    illegalInstr_ = true;
	    break;
	case 0x27:
	    Opcode_ = STDF; instAlignSize_ = 8; nonzbits_ = nonzbitstest1(); 
	    break;
	case 0x28:
	case 0x29:
	case 0x2a:
	case 0x2b:
	case 0x2c:
	    illegalInstr_ = true;
	    break;
	case 0x2d:
	    // illegal_instruction (fcn = 5-15)
	    Opcode_ = PREFETCH; 
	    instAlignSize_ = 64; 
	    nonzbits_ = nonzbitstest1(); 
	    tmp = fcn();
	    if (tmp >= 5 && tmp <= 15) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x2e:
	case 0x2f:
	    illegalInstr_ = true;
	    break;

	case 0x30: Opcode_ = LDFA; instAlignSize_ = 4; break;
	case 0x31:
	    illegalInstr_ = true;
	    break;
	case 0x32: 
	    Opcode_ = LDQFA; 
	    instAlignSize_ = 4; 
	    illegalInstr_ = true;
	    break;
	case 0x33: Opcode_ = LDDFA; instAlignSize_ = 8; break;
	case 0x34: Opcode_ = STFA; instAlignSize_ = 4; break;
	case 0x35:
	    illegalInstr_ = true;
	    break;
	case 0x36: 
	    Opcode_ = STQFA; 
	    instAlignSize_ = 4; 
	    illegalInstr_ = true;
	    break;
	case 0x37: Opcode_ = STDFA; instAlignSize_ = 8; break;
	case 0x38:
	case 0x39:
	case 0x3a:
	case 0x3b:
	    illegalInstr_ = true;
	    break;
	case 0x3c:
	    Opcode_ = CASA; instAlignSize_ = 4; nonzbits_ = nonzbitstestcasa();
	    break;
	case 0x3d: 
	    Opcode_ = PREFETCHA; 
	    instAlignSize_ = 64; 
	    tmp = fcn();
	    if (tmp >= 5 && tmp <= 15) {
		illegalInstr_ = true;
	    }
	    break;
	case 0x3e:
	    Opcode_ = CASXA; instAlignSize_ = 8; nonzbits_ = nonzbitstestcasa();
	    break;
	case 0x3f:
	    illegalInstr_ = true;
	    break;
	default:
	    illegalInstr_ = true;
	    break;
	}
	break;

    default:
	illegalInstr_ = true;
	break;
    }
}

/////////////////////////////////////////////////////////
bool InstructionWord::isIllegalInstrTrap(bool priv, bool  hpriv, int tl, int asi)
{
    // handle illegal_instruction trap that can only be checked right before
    // the execution of the instruction.

    if (illegalInstr_ || nonzbits_) {
	// if already an illegal_instruciton after decode, go no further.
	return true;
    }

    uint tmp;
    bool illegalInstrTrap = false;

    switch (op()) {
    case 2:
	switch (op3()) {
	case 0x2a: // RDPR
	    // illegal_instruction ((rs1 = 15-31) or ((rs1 <= 3) and (TL = 0)))
	    if ((rs1() <= PR_TT) && (tl == 0) && (priv || hpriv)) {
		illegalInstrTrap = true;
	    }
	    break;

	case 0x30: // WRASR
	    // illegal_instruction (WRSTICK (outside of hyperprivileged mode),
	    //                     (WRASR with rd = 1, 4, 5, 7-14, 16-18, 26-31;
	    //                      WRASR with rd = 15 and (rs1 != 0 or i != 1))
	    if (!hpriv && ((rd() == ASR_STICK) || (sir_ == true))) {
		illegalInstrTrap = true;
	    }
	    break;

	case 0x32: // WRPR
	    // illegal_instruction ((rd = 15-31) or ((rd <= 3) and (TL = 0)),
	    //                      (rd = 4 (TICK) outside of hyperprivileged mode)
	    tmp = rd();
	    //if ((tmp <= PR_TT && tl == 0) || 
	    if (((tmp <= PR_TT) && (tl == 0) && (priv || hpriv)) || 
		((tmp == PR_TICK) && priv && !hpriv)) {
		illegalInstrTrap = true;
	    }
	    break;

	case 0x3a: // Tcc
	    // illegal_instruction 
	    //   ((cc0 = 1) or
	    //   ((PSTATE.priv = 0) and (SWTN > 127)) or
	    //   (instruction<29> != 0) or
	    //   ((i = 0) and (instruction<10:5> != 0)) or
	    //   ((i = 1) and (instruction<10:8> != 0)))
	    if ((!priv && !hpriv) && ((iw_ >> 7) & 0x1)) {
		illegalInstrTrap = true;
	    }
	    break;

	case 0x3e: // DONE & RETRY
	    // illegal_instruction (TL = 0)
	    // Paul to require change to Sun SPARC done/retry so that tl=0 
	    // alone is enough
	    //---> the request is rejected, so we have to check priv/hpriv
	    //     as well.
	    if ((tl == 0) && (priv || hpriv)) { 
		illegalInstrTrap = true;
	    }
	    break;
	}
	break;
//     case 3:
// 	switch (op3()) {
// 	case 0x37: // STDFA, STPARTIALF, STSHORTF
// 	    if (i() && ((asi >= 0xc0 && asi <= 0xc5) || 
// 			(asi >= 0xc8 && asi <= 0xcd))) {
// 		illegalInstrTrap = true;
// 	    }
// 	    break;
// 	}
// 	break;
    }
    
    return illegalInstrTrap;
}

/////////////////////////////////////////////////////////
bool InstructionWord::isPrivOpcodeTrap(bool priv, bool  hpriv, int tl)
{
    uint tmp;
    bool privOpcodeTrap = false;

    switch (op()) {
    case 2:
	switch (op3()) {
	case 0x28: // RDASR 
	    // privileged_opcode (RDSOFTINT, RDTICK_CMPR, and RDSTICK (p-npt),
	    //                    RDSTICK_CMPR, and RDPCR)
	    tmp = rs1();
	    if ( tmp == 16 ||  // PCR
		 tmp == 22 ||  // SOFTINT
		 tmp == 23 ||  // TICK_CMPR
		 tmp == 25 ) { // STICK_CMPR_REG
		if (!priv) {
		    privOpcodeTrap = true;
		}
	    }
	    break;
	case 0x2a: // RDPR
	    // privileged_opcode ((PSTATE.priv = 0) and (HSTATE.hpriv = 0))
	    if (!priv && !hpriv) {
		privOpcodeTrap = true;
	    }
	    break;
	case 0x30: // WRASR
	    // privileged_opcode (WRSOFTINT_SET, WRSOFTINT_CLR, WRSOFTINT,
	    //                    WRTICK_CMPR, and WRSTICK_CMPR,)
	    // An attempt to execute a WRSOFTINT_SET, WRSOFTINT_CLR, WRSOFTINT,
	    // WRTICK_CMPR, or WRSTICK_CMPR instruction in nonprivileged mode 
	    // and HPSTATE.hpriv = 0 causes a privileged_opcode exception.
	    tmp = rd();
	    if (!priv && !hpriv) {
		if ((tmp >= 20 && tmp <= 23) || tmp == 25) {
		    privOpcodeTrap = true;
		}
	    }
	    break;
// 	    if ( tmp == 4 ||	// TICK
// 		 tmp == 16 ||	// PCR
// 		 (tmp >= 20 && tmp <= 25) ) {
// 		if (!priv && !hpriv) {
// 		    privOpcodeTrap = true;
// 		}
// 	    }
// 	    break;
	case 0x31: // SAVED/RESTORED
	    // privileged_opcode (PSTATE.priv = 0)
	    if (!priv) {
		privOpcodeTrap = true;
	    }
	    break;
	case 0x32: // WRPR
	    // privileged_opcode ((PSTATE.priv = 0) and (HSTATE.hpriv = 0))
	    if (!priv && !hpriv) {
		privOpcodeTrap = true;
	    }
	    break;
// 	case 0x36: // SHUTDOWN
// 	    // privileged_opcode
// 	    if (!priv && !hpriv) {
// 		privOpcodeTrap = true;
// 	    }
// 	    break;

	case 0x3e: // DONE & RETRY 
	    // privileged_opcode (PSTATE.priv = 0)
	    if (!priv && !hpriv) {
		privOpcodeTrap = true;
	    }
	    break;
	}
	break;
    }
    
    return privOpcodeTrap;
}

/////////////////////////////////////////////////////////

bool InstructionWord::readsRs1() const
{
    return spix_sparc_iop_regpos( spix_sparc_iop( SPIX_SPARC_V9, &iw_), SPIX_SPARC_RUPOS_RS1 ) != SPIX_SPARC_RUACT_NONE;
}

/////////////////////////////////////////////////////////

bool InstructionWord::readsRs2() const
{
    return spix_sparc_iop_regpos( spix_sparc_iop( SPIX_SPARC_V9, &iw_), SPIX_SPARC_RUPOS_RS2 ) != SPIX_SPARC_RUACT_NONE;
}

/////////////////////////////////////////////////////////

void InstructionWord::fcn( uint32_t value )
{
    SET_BITS( iw_, 29, 25, value );
}

/////////////////////////////////////////////////////////


void InstructionWord::mode( uint32_t value )
{
    SET_BITS( iw_, 2, 0, value );
}

//=============================================================================
//=============================================================================
void InstructionWord::decodeFpuOpcode()
{

    switch (op()) {
    case 0:
	switch (op2()) {
	case 5: // FBPfcc
	    break;
	case 6: // FBfcc
	    break;
	}
	break;
    case 2:
	switch (op3()) {
	case 0x34: // FPop1
	{
	    uint_t bits_8_4 = opf() >> 4;
	    uint_t bits_3_0 = opf() & 0x0f;
	    bool compareBits = false;
	    switch ( bits_8_4 ) {
	    case 0x8:
		switch ( bits_3_0 ) {
		case 0x1: // A.14 from V9 Instr Defns
		case 0x2:
		case 0x3:
		case 0x4: // A.16 from V9 Instr Defns
		case 0x8:
		case 0xc:
		    compareBits = true;
		    break;
		}
		break;
	    case 0xd:
		if ( bits_3_0 > 0 && bits_3_0 < 4 ) {
		    compareBits = true;
		}
		break;
	    case 0xc:
		switch ( bits_3_0 ) {
		case 0x9: // A.15 from V9 Instr Defns
		case 0xd:
		case 0x6:
		case 0xe:
		case 0x7:
		case 0xb:
		case 0x4: // A.16 from V9 Instr Defns
		case 0x8:
		case 0xc:
		    compareBits = true;
		    break;
		}
		break;
	    case 0x0:
		switch ( bits_3_0 ) {
		case 0x1:
		case 0x2:
		case 0x3:
		case 0x5:
		case 0x6:
		case 0x7:
		case 0x9:
		case 0xa:
		case 0xb:
		    compareBits = true;
		    break;
		}
		break;
	    case 0x2:
		if ( bits_3_0 == 0x9 || bits_3_0 == 0xa || bits_3_0 == 0xb ) {
		    compareBits = true;
		}
		break;
	    } // switch( bits_8_4 )
	    
	    if ( compareBits && NumericUtils::getBits( iw_, 18, 14 ) != 0 ) {
		nonzbitsFpu = true;
	    }	    
	    break;
	}
	case 0x35: // FPop2
	    break;
	case 0x36: // extended or VIS operations
	{
	    uint_t opf_bits = opf();
	    switch ( opf_bits ) {
	    case 0x060:   // FZERO
	    case 0x061:   // FZEROS
	    case 0x07E:   // FONE
	    case 0x07F:   // 13.5.6 Logical Operate Instructions in USII User's Manual 1997
	    {
		if ( ( NumericUtils::getBits( iw_, 18, 14 ) != 0 ) ||
		    ( NumericUtils::getBits( iw_, 4, 0 ) != 0 ) ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x074:   // FSRC1
	    case 0x075:   // FSRC1S
	    case 0x06A:   // FNOT1
	    case 0x06B:   // 13.5.6 Logical Operate Instructions in USII User's Manual 1997
	    {
		if ( NumericUtils::getBits( iw_, 4, 0 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x078:   // FSRC2
	    case 0x079:   // FSRC2S
	    case 0x066:   // FNOT2
	    case 0x067:   // 13.5.6 Logical Operate Instructions in USII User's Manual 1997
	    case 0x03B:   // FPACK16
	    case 0x03D:   // FPACKFIX
	    case 0x04D:   // 13.5.3 Logical Operate Instructions in USII User's Manual 1997
	    {
		if ( NumericUtils::getBits( iw_, 18, 14 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x017:   // LZD     Vis3.0
	    case 0x1C4:   // SFiTOs  Vis3.0
	    case 0x1D1:   // SFsTOi  Vis3.0
	    {
		if ( NumericUtils::getBits( iw_, 18, 14 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x081:   // SIAM Vis2.0
	    {
		if ( NumericUtils::getBits( iw_, 29, 25 ) != 0 ) {
		    nonzbitsFpu = true;
		} 
		else if ( NumericUtils::getBits( iw_, 18, 14 ) != 0 ) {
		    nonzbitsFpu = true;
		} 
		else if ( NumericUtils::getBits( iw_, 4, 3 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x109:   // SFABSs Vis3.0
	    case 0x105:   // SFNEGs Vis3.0
	    {
		if ( NumericUtils::getBits( iw_, 18, 14 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x151:   // FLCMPS Vis3.0
	    case 0x152:   // FLCMPD Vis3.0
	    {
		if ( NumericUtils::getBits( iw_, 29, 27 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    case 0x171:   // SFCMPEQs Vis3.0
	    case 0x173:   // SFCMPNEs Vis3.0
	    case 0x175:   // SFCMPGTs Vis3.0
	    case 0x177:   // SFCMPLEs Vis3.0
	    {
		if ( NumericUtils::getBits( iw_, 29, 25 ) != 0 ) {
		    nonzbitsFpu = true;
		}
		break;
	    }
	    }    
	    break;
	}
	}
	uint32_t _op3 = op3() & 0x7;
	uint32_t _opf = opf();
	switch (op2()) {
	    case OP2_101:
	    {
		switch (_op3) {
	  	    case OP3_100:
		    {
			checkType_f4b_instr();
			break;
		    }
		}
		break;
	    }   // case OP2_101
	    case OP2_110:
	    {
		switch (_op3) {
		    case OP3_100:
		    {
			if ( (_opf & OPF_0_01XX_XXXX_MASK) == OPF_0_01XX_XXXX ) {
			    checkType_f3n_instr();
			} 
			else {
			    checkType_f3l_instr();
			}
			break;
		    }
		    case OP3_101:
		    {
			if ( (_opf & OPF_X_0101_XXXX_MASK) == OPF_X_0101_XXXX ) {
			    checkType_f3m_instr();
			} 
			else if ( (_opf & OPF_0_XXXX_01XX_MASK) == OPF_0_XXXX_01XX ) {
			    checkType_f4c_instr();
			} 
			else {
			    checkType_f4d_instr();
			}
			break;
		    }
		    case OP3_110:
		    case OP3_111:
			checkType_vis3_instr();
			break;
		}   // switch OP1_10,OP2_110,op3
		break;
	    }   // case OP2_110
	    case OP2_111:
	    {
		switch (_op3) {
		    case OP3_111:
		      switch (_opf & 0xf) {
		          case 1: instrTypeFpu = FUMADDS; break;
		          case 2: instrTypeFpu = FUMADDD; break;
		          case 5: instrTypeFpu = FUMSUBS; break;
		          case 6: instrTypeFpu = FUMSUBD; break;
		          case 9: instrTypeFpu = FNUMSUBS; break;
		          case 10: instrTypeFpu = FNUMSUBD; break;
		          case 13: instrTypeFpu = FNUMADDS; break;
		          case 14: instrTypeFpu = FNUMADDD; break;
			      //default: illegalInstrFpu_ = true;
		      }
		      break;
		}
		break;
	    }
	}   // switch OP1_10,op2
	break;
    }
}

//=============================================================================
//=============================================================================
void InstructionWord::checkType_f3n_instr()
{
    switch ( opf() ) {
        case OPF_0_0100_0001:   instrTypeFpu = FADDS;   break;
        case OPF_0_0100_0010:   instrTypeFpu = FADDD;   break;
        case OPF_0_0100_0011:   instrTypeFpu = FADDQ;   break;
        case OPF_0_0100_0101:   instrTypeFpu = FSUBS;   break;
        case OPF_0_0100_0110:   instrTypeFpu = FSUBD;   break;
        case OPF_0_0100_0111:   instrTypeFpu = FSUBQ;   break;
        case OPF_0_0100_1001:   instrTypeFpu = FMULS;   break;
        case OPF_0_0100_1010:   instrTypeFpu = FMULD;   break;
        case OPF_0_0100_1011:   instrTypeFpu = FMULQ;   break;
        case OPF_0_0100_1101:   instrTypeFpu = FDIVS;   break;
        case OPF_0_0100_1110:   instrTypeFpu = FDIVD;   break;
        case OPF_0_0100_1111:   instrTypeFpu = FDIVQ;   break;
        case OPF_0_0101_0001:   instrTypeFpu = FNADDS;  break;
        case OPF_0_0101_0010:   instrTypeFpu = FNADDD;  break;
        case OPF_0_0101_1001:   instrTypeFpu = FNMULS;  break;
        case OPF_0_0101_1010:   instrTypeFpu = FNMULD;  break;
        case OPF_0_0110_1001:   instrTypeFpu = FSMULD;  break;
        case OPF_0_0110_1110:   instrTypeFpu = FDMULQ;  break;
        case OPF_0_0111_1001:   instrTypeFpu = FNSMULD; break;
	    //default: illegalInstrFpu_ = true;
    }

//     if (isUnimplementedV9Instruction( iw, instrTypeFpu )) {
// 	RIESLING_TRAP( V9_Trap::illegal_instruction );
//     }
}

//=============================================================================
//=============================================================================
void InstructionWord::checkType_f3l_instr()
{
    switch (opf()) {
        case OPF_0_0000_0001:    instrTypeFpu = FMOVS;    break;
        case OPF_0_0000_0010:    instrTypeFpu = FMOVD;    break;
        case OPF_0_0000_0011:    instrTypeFpu = FMOVQ;    break;
        case OPF_0_0000_0101:    instrTypeFpu = FNEGS;    break;
        case OPF_0_0000_0110:    instrTypeFpu = FNEGD;    break;
        case OPF_0_0000_0111:    instrTypeFpu = FNEGQ;    break;
        case OPF_0_0000_1001:    instrTypeFpu = FABSS;    break;
        case OPF_0_0000_1010:    instrTypeFpu = FABSD;    break;
        case OPF_0_0000_1011:    instrTypeFpu = FABSQ;    break;
        case OPF_0_0010_1001:    instrTypeFpu = FSQRTS;   break;
        case OPF_0_0010_1010:    instrTypeFpu = FSQRTD;   break;
        case OPF_0_0010_1011:    instrTypeFpu = FSQRTQ;   break;
        case OPF_0_1000_0001:    instrTypeFpu = FSTOX;    break;
        case OPF_0_1000_0010:    instrTypeFpu = FDTOX;    break;
        case OPF_0_1000_0011:    instrTypeFpu = FQTOX;    break;
        case OPF_0_1000_0100:    instrTypeFpu = FXTOS;    break;
        case OPF_0_1000_1000:    instrTypeFpu = FXTOD;    break;
        case OPF_0_1000_1100:    instrTypeFpu = FXTOQ;    break;
        case OPF_0_1100_0100:    instrTypeFpu = FITOS;    break;
        case OPF_0_1100_0110:    instrTypeFpu = FDTOS;    break;
        case OPF_0_1100_1110:    instrTypeFpu = FDTOQ;    break;
        case OPF_0_1100_0111:    instrTypeFpu = FQTOS;    break;
        case OPF_0_1100_1011:    instrTypeFpu = FQTOD;    break;
        case OPF_0_1100_1000:    instrTypeFpu = FITOD;    break;
        case OPF_0_1100_1001:    instrTypeFpu = FSTOD;    break;
        case OPF_0_1100_1100:    instrTypeFpu = FITOQ;    break;
        case OPF_0_1100_1101:    instrTypeFpu = FSTOQ;    break;
        case OPF_0_1101_0001:    instrTypeFpu = FSTOI;    break;
        case OPF_0_1101_0010:    instrTypeFpu = FDTOI;    break;
        case OPF_0_1101_0011:    instrTypeFpu = FQTOI;    break;
	    //default: illegalInstrFpu_ = true;
    }

//     if (isUnimplementedV9Instruction(iw, instrTypeFpu) ||
// 	iw.fguNonZeroReservedBits()) {
//         RIESLING_TRAP( V9_Trap::illegal_instruction );
//     }
}

//=============================================================================
//=============================================================================
void InstructionWord::checkType_f3m_instr()
{
    switch (opf()) {
        case OPF_0_0101_0001:    instrTypeFpu = FCMPS;    break;
	case OPF_0_0101_0010:    instrTypeFpu = FCMPD;    break;
	case OPF_0_0101_0011:    instrTypeFpu = FCMPQ;    break;
	case OPF_0_0101_0101:    instrTypeFpu = FCMPES;   break;
	case OPF_0_0101_0110:    instrTypeFpu = FCMPED;   break;
	case OPF_0_0101_0111:    instrTypeFpu = FCMPEQ;   break;
	default: illegalInstrFpu_ = true;
    }

    if (NumericUtils::getBits(iw_, 29, 27) != 0) {
	nonzbitsFpu = true;
    }

//     if (isUnimplementedV9Instruction(iw, instrTypeFpu) ||
// 	(iw.get(29,27) != 0)) {
// 	RIESLING_TRAP( V9_Trap::illegal_instruction );
//     }
}

//=============================================================================
//=============================================================================
void InstructionWord::checkType_f4b_instr()
{
    switch ( cond() ) {
        case COND_0001:    	instrTypeFpu = MOVFNE;     break;
	case COND_1001:    	instrTypeFpu = MOVFE;      break;
	case COND_0000:    	instrTypeFpu = MOVFN;      break;
	case COND_0010:    	instrTypeFpu = MOVFLG;     break;
	case COND_0011:    	instrTypeFpu = MOVFUL;     break;
	case COND_0100:    	instrTypeFpu = MOVFL;      break;
	case COND_0101:    	instrTypeFpu = MOVFUG;     break;
	case COND_0110:    	instrTypeFpu = MOVFG;      break;
	case COND_0111:    	instrTypeFpu = MOVFU;      break;
	case COND_1000:    	instrTypeFpu = MOVFA;      break;
	case COND_1010:    	instrTypeFpu = MOVFUE;     break;
	case COND_1011:    	instrTypeFpu = MOVFGE;     break;
	case COND_1100:    	instrTypeFpu = MOVFUGE;    break;
	case COND_1101:    	instrTypeFpu = MOVFLE;     break;
	case COND_1110:    	instrTypeFpu = MOVFULE;    break;
	case COND_1111:    	instrTypeFpu = MOVFO;      break;
	    //default: illegalInstrFpu_ = true;
    }

//     if (isUnimplementedV9Instruction( iw, instrTypeFpu )) {
// 	RIESLING_TRAP( V9_Trap::illegal_instruction );
//     }
}


//=============================================================================
//=============================================================================
void InstructionWord::checkType_f4c_instr()
{
    switch (opf() & 0x1F) {
    case OPF_LOW_0_0101:
	{
	    switch (rcond()) {
	        case RCOND_001:    instrTypeFpu = FMOVRSE;    break;
	        case RCOND_010:    instrTypeFpu = FMOVRSLEZ;  break;
		case RCOND_011:    instrTypeFpu = FMOVRSLZ;   break;
		case RCOND_101:    instrTypeFpu = FMOVRSNE;   break;
		case RCOND_110:    instrTypeFpu = FMOVRSGZ;   break;
		case RCOND_111:    instrTypeFpu = FMOVRSGEZ;  break;
		default: illegalInstrFpu_ = true;
	    }
	    break;
	}
    case OPF_LOW_0_0110:
	{
	    switch (rcond()) {
		case RCOND_001:    instrTypeFpu = FMOVRDE;    break;
		case RCOND_010:    instrTypeFpu = FMOVRDLEZ;  break;
		case RCOND_011:    instrTypeFpu = FMOVRDLZ;   break;
		case RCOND_101:    instrTypeFpu = FMOVRDNE;   break;
		case RCOND_110:    instrTypeFpu = FMOVRDGZ;   break;
	        case RCOND_111:    instrTypeFpu = FMOVRDGEZ;  break;
	        default: illegalInstrFpu_ = true;
	    }
	    break;
	}
    case OPF_LOW_0_0111:
	{
	    switch (rcond()) {
		case RCOND_001:    instrTypeFpu = FMOVRQE;    break;
		case RCOND_010:    instrTypeFpu = FMOVRQLEZ;  break;
		case RCOND_011:    instrTypeFpu = FMOVRQLZ;   break;
		case RCOND_101:    instrTypeFpu = FMOVRQNE;   break;
		case RCOND_110:    instrTypeFpu = FMOVRQGZ;   break;
		case RCOND_111:    instrTypeFpu = FMOVRQGEZ;  break;
	        default: illegalInstrFpu_ = true;
	    }
	    break;
	}
    default:
	illegalInstrFpu_ = true;
	break;
    }

    if (NumericUtils::getBits(iw_, 13, 13) != 0) {
	nonzbitsFpu = true;
    }

//     if (isUnimplementedV9Instruction(iw, instrTypeFpu) ||
// 	illegal_rcond ||
// 	(iw.get( 13, 13 ) != 0)) 
//     {
//         RIESLING_TRAP( V9_Trap::illegal_instruction );
//     }
}


//=============================================================================
//=============================================================================
void InstructionWord::checkType_f4d_instr()
{
    switch (opf() & ~OPF_0_XX00_0000)  {
        case OPF_0_XX00_0001: 
	{
	    switch (cond()) {
		case COND_1000:    instrTypeFpu = FMOVFSA;      break;
		case COND_0000:    instrTypeFpu = FMOVFSN;      break;
		case COND_0111:    instrTypeFpu = FMOVFSU;      break;
		case COND_0110:    instrTypeFpu = FMOVFSG;      break;
		case COND_0101:    instrTypeFpu = FMOVFSUG;     break;
		case COND_0100:    instrTypeFpu = FMOVFSL;      break;
		case COND_0011:    instrTypeFpu = FMOVFSUL;     break;
		case COND_0010:    instrTypeFpu = FMOVFSLG;     break;
		case COND_0001:    instrTypeFpu = FMOVFSNE;     break;
		case COND_1001:    instrTypeFpu = FMOVFSE;      break;
		case COND_1010:    instrTypeFpu = FMOVFSUE;     break;
		case COND_1011:    instrTypeFpu = FMOVFSGE;     break;
		case COND_1100:    instrTypeFpu = FMOVFSUGE;    break;
		case COND_1101:    instrTypeFpu = FMOVFSLE;     break;
		case COND_1110:    instrTypeFpu = FMOVFSULE;    break;
		case COND_1111:    instrTypeFpu = FMOVFSO;      break;
		    //default: illegalInstrFpu_ = true;
	    }
	    break;
	}

	case OPF_0_XX00_0010: 
	{
	    switch (cond()) {
		case COND_1000:    instrTypeFpu = FMOVFDA;      break;
		case COND_0000:    instrTypeFpu = FMOVFDN;      break;
		case COND_0111:    instrTypeFpu = FMOVFDU;      break;
		case COND_0110:    instrTypeFpu = FMOVFDG;      break;
		case COND_0101:    instrTypeFpu = FMOVFDUG;     break;
		case COND_0100:    instrTypeFpu = FMOVFDL;      break;
		case COND_0011:    instrTypeFpu = FMOVFDUL;     break;
		case COND_0010:    instrTypeFpu = FMOVFDLG;     break;
		case COND_0001:    instrTypeFpu = FMOVFDNE;     break;
		case COND_1001:    instrTypeFpu = FMOVFDE;      break;
		case COND_1010:    instrTypeFpu = FMOVFDUE;     break;
		case COND_1011:    instrTypeFpu = FMOVFDGE;     break;
		case COND_1100:    instrTypeFpu = FMOVFDUGE;    break;
		case COND_1101:    instrTypeFpu = FMOVFDLE;     break;
		case COND_1110:    instrTypeFpu = FMOVFDULE;    break;
		case COND_1111:    instrTypeFpu = FMOVFDO;      break;
		    //default: illegalInstrFpu_ = true;
	    }
	    break;
	}

	case OPF_0_XX00_0011: 
	{
	    switch (cond()) {
		case COND_1000:    instrTypeFpu = FMOVFQA;      break;
		case COND_0000:    instrTypeFpu = FMOVFQN;      break;
		case COND_0111:    instrTypeFpu = FMOVFQU;      break;
		case COND_0110:    instrTypeFpu = FMOVFQG;      break;
		case COND_0101:    instrTypeFpu = FMOVFQUG;     break;
		case COND_0100:    instrTypeFpu = FMOVFQL;      break;
		case COND_0011:    instrTypeFpu = FMOVFQUL;     break;
		case COND_0010:    instrTypeFpu = FMOVFQLG;     break;
		case COND_0001:    instrTypeFpu = FMOVFQNE;     break;
		case COND_1001:    instrTypeFpu = FMOVFQE;      break;
		case COND_1010:    instrTypeFpu = FMOVFQUE;     break;
		case COND_1011:    instrTypeFpu = FMOVFQGE;     break;
		case COND_1100:    instrTypeFpu = FMOVFQUGE;    break;
		case COND_1101:    instrTypeFpu = FMOVFQLE;     break;
		case COND_1110:    instrTypeFpu = FMOVFQULE;    break;
		case COND_1111:    instrTypeFpu = FMOVFQO;      break;
		    //default: illegalInstrFpu_ = true;
	    }
// 	    if ( instrTypeFpu != UNKNOWN_INSTR ) {
// 	        RIESLING_TRAP( V9_Trap::illegal_instruction );
// 	    }
	    break;
	}

	case OPF_1_0000_0001:
	case OPF_1_1000_0001: 
	{
	    switch (cond()) {
		case COND_1000:    instrTypeFpu = FMOVSA;      break;
		case COND_0000:    instrTypeFpu = FMOVSN;      break;
		case COND_1001:    instrTypeFpu = FMOVSNE;     break;
		case COND_0001:    instrTypeFpu = FMOVSE;      break;
		case COND_1010:    instrTypeFpu = FMOVSG;      break;
		case COND_0010:    instrTypeFpu = FMOVSLE;     break;
		case COND_1011:    instrTypeFpu = FMOVSGE;     break;
		case COND_0011:    instrTypeFpu = FMOVSL;      break;
		case COND_1100:    instrTypeFpu = FMOVSGU;     break;
		case COND_0100:    instrTypeFpu = FMOVSLEU;    break;
		case COND_1101:    instrTypeFpu = FMOVSCC;     break;
		case COND_0101:    instrTypeFpu = FMOVSCS;     break;
		case COND_1110:    instrTypeFpu = FMOVSPOS;    break;
		case COND_0110:    instrTypeFpu = FMOVSNEG;    break;
		case COND_1111:    instrTypeFpu = FMOVSVC;     break;
		case COND_0111:    instrTypeFpu = FMOVSVS;     break;
		    //default: illegalInstrFpu_ = true;
	    }
	    break;
	}

	case OPF_1_0000_0010:
	case OPF_1_1000_0010: 
	{
	    switch (cond()) {
		case COND_1000:    instrTypeFpu = FMOVDA;      break;
		case COND_0000:    instrTypeFpu = FMOVDN;      break;
		case COND_1001:    instrTypeFpu = FMOVDNE;     break;
		case COND_0001:    instrTypeFpu = FMOVDE;      break;
		case COND_1010:    instrTypeFpu = FMOVDG;      break;
		case COND_0010:    instrTypeFpu = FMOVDLE;     break;
		case COND_1011:    instrTypeFpu = FMOVDGE;     break;
		case COND_0011:    instrTypeFpu = FMOVDL;      break;
		case COND_1100:    instrTypeFpu = FMOVDGU;     break;
		case COND_0100:    instrTypeFpu = FMOVDLEU;    break;
		case COND_1101:    instrTypeFpu = FMOVDCC;     break;
		case COND_0101:    instrTypeFpu = FMOVDCS;     break;
		case COND_1110:    instrTypeFpu = FMOVDPOS;    break;
		case COND_0110:    instrTypeFpu = FMOVDNEG;    break;
		case COND_1111:    instrTypeFpu = FMOVDVC;     break;
		case COND_0111:    instrTypeFpu = FMOVDVS;     break;
		    //default: illegalInstrFpu_ = true;
	    }
	    break;
	}

	case OPF_1_0000_0011:
	case OPF_1_1000_0011: 
	{
	    switch (cond()) {
		case COND_1000:    instrTypeFpu = FMOVQA;      break;
		case COND_0000:    instrTypeFpu = FMOVQN;      break;
		case COND_1001:    instrTypeFpu = FMOVQNE;     break;
		case COND_0001:    instrTypeFpu = FMOVQE;      break;
		case COND_1010:    instrTypeFpu = FMOVQG;      break;
		case COND_0010:    instrTypeFpu = FMOVQLE;     break;
		case COND_1011:    instrTypeFpu = FMOVQGE;     break;
		case COND_0011:    instrTypeFpu = FMOVQL;      break;
		case COND_1100:    instrTypeFpu = FMOVQGU;     break;
		case COND_0100:    instrTypeFpu = FMOVQLEU;    break;
		case COND_1101:    instrTypeFpu = FMOVQCC;     break;
		case COND_0101:    instrTypeFpu = FMOVQCS;     break;
		case COND_1110:    instrTypeFpu = FMOVQPOS;    break;
		case COND_0110:    instrTypeFpu = FMOVQNEG;    break;
		case COND_1111:    instrTypeFpu = FMOVQVC;     break;
		case COND_0111:    instrTypeFpu = FMOVQVS;     break;
		    //default: illegalInstrFpu_ = true;
	    }
	    break;
	}

	default:
	    illegalInstrFpu_ = true;
	    break;
    }

    if (NumericUtils::getBits(iw_, 18, 18) != 0) {
	nonzbitsFpu = true;
    }

    uint32_t cc_index = opf_cc();
    if ((cc_index == 0x5) || (cc_index == 0x7)) {
	// cannot just throw illegal_instruction, N1 still uses fp_other
	//illegalInstr_ = true;
	illegalInstrCcFpu_ = true;
    }

//     if (isUnimplementedV9Instruction(iw, instrTypeFpu) ||
// 	(iw.get( 18, 18 ) != 0) ||
// 	(cc_index == 0x5) ||
// 	(cc_index == 0x7))
//     {
//         RIESLING_TRAP( V9_Trap::illegal_instruction );
//     }
}

//=============================================================================
//=============================================================================
void InstructionWord::checkType_vis3_instr()
{
    uint32_t _op3 = op3() & 0x7;
    uint32_t _opf = opf();

    if (_op3 == OP3_110) {
	switch (_opf) {
	    case  OPF_0_0001_0001:    instrTypeFpu = ADDXC;       break;
	    case  OPF_0_0001_0011:    instrTypeFpu = ADDXCCC;     break;

	    case  OPF_0_0001_1011:    instrTypeFpu = CMASK8;      break;
	    case  OPF_0_0001_1101:    instrTypeFpu = CMASK16;     break;
	    case  OPF_0_0001_1111:    instrTypeFpu = CMASK32;     break;

	    case  OPF_0_0100_0100:    instrTypeFpu = FCHKSM16;    break;

	    case  OPF_1_0101_0001:    instrTypeFpu = FLCMPS;      break;
	    case  OPF_1_0101_0010:    instrTypeFpu = FLCMPD;      break;

	    case  OPF_0_0100_0000:    instrTypeFpu = FMEAN16;     break;

	    case  OPF_0_0100_1111:    instrTypeFpu = FMERGESP;    break;

	    case  OPF_0_0101_1000:    instrTypeFpu = FPADDS16;    break;
	    case  OPF_0_0101_1001:    instrTypeFpu = FPADDS16S;   break;
	    case  OPF_0_0101_1010:    instrTypeFpu = FPADDS32;    break;
	    case  OPF_0_0101_1011:    instrTypeFpu = FPADDS32S;   break;

	    case  OPF_0_0100_0010:    instrTypeFpu = FPADD64;     break;

	    case  OPF_0_0101_1100:    instrTypeFpu = FPSUBS16;    break;
	    case  OPF_0_0101_1101:    instrTypeFpu = FPSUBS16S;   break;
	    case  OPF_0_0101_1110:    instrTypeFpu = FPSUBS32;    break;
	    case  OPF_0_0101_1111:    instrTypeFpu = FPSUBS32S;   break;

	    case  OPF_0_0100_0110:    instrTypeFpu = FPSUB64;     break;

	    case  OPF_0_0010_0001:    instrTypeFpu = FSHL16;      break;
	    case  OPF_0_0010_0011:    instrTypeFpu = FSHRL16;     break;
	    case  OPF_0_0010_0101:    instrTypeFpu = FSHL32;      break;
	    case  OPF_0_0010_0111:    instrTypeFpu = FSHRL32;     break;
	    case  OPF_0_0010_1001:    instrTypeFpu = FSHLAS16;    break;
	    case  OPF_0_0010_1011:    instrTypeFpu = FSHRA16;     break;
	    case  OPF_0_0010_1101:    instrTypeFpu = FSHLAS32;    break;
	    case  OPF_0_0010_1111:    instrTypeFpu = FSHRA32;     break;

	    case  OPF_1_0010_0000:    instrTypeFpu = FUCMPLE8;    break;
	    case  OPF_1_0010_0010:    instrTypeFpu = FUCMPNE8;    break;
	    case  OPF_1_0010_1000:    instrTypeFpu = FUCMPGT8;    break;
	    case  OPF_1_0010_1010:    instrTypeFpu = FUCMPEQ8;    break;

	    case  OPF_0_0001_0111:    instrTypeFpu = LZD;         break;
	    case  OPF_0_0011_1111:    instrTypeFpu = PDISTN;      break;

	    case  OPF_1_0000_1001:    instrTypeFpu = SFABSS;      break;
	    case  OPF_1_0000_0101:    instrTypeFpu = SFNEGS;      break;

	    case  OPF_1_0100_0001:    instrTypeFpu = SFADDS;      break;
	    case  OPF_1_0100_0101:    instrTypeFpu = SFSUBS;      break;
	    case  OPF_1_0100_1001:    instrTypeFpu = SFMULS;      break;

	    case  OPF_1_1100_0100:    instrTypeFpu = SFITOS;      break;
	    case  OPF_1_1101_0001:    instrTypeFpu = SFSTOI;      break;

	    case  OPF_0_0001_0110:    instrTypeFpu = UMULXHI;     break;

	    case  OPF_1_0001_0101:    instrTypeFpu = XMULX;       break;
	    case  OPF_1_0001_0110:    instrTypeFpu = XMULXHI;     break;
	    case  OPF_1_0001_0000:    instrTypeFpu = MOVDTOX;     break;
	    case  OPF_1_0001_1000:    instrTypeFpu = MOVXTOD;     break;

		//default: illegalInstrFpu_ = true;
	}
    }
    else if (_op3 == OP3_111) {
	switch (_opf & 0xf) {
            case 1: instrTypeFpu = FMADDS; break;
            case 2: instrTypeFpu = FMADDD; break;
            case 5: instrTypeFpu = FMSUBS; break;
            case 6: instrTypeFpu = FMSUBD; break;
            case 9: instrTypeFpu = FNMSUBS; break;
            case 10: instrTypeFpu = FNMSUBD; break;
            case 13: instrTypeFpu = FNMADDS; break;
            case 14: instrTypeFpu = FNMADDD; break;
		//default: illegalInstrFpu_ = true;
	}
    }
}
